unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ComCtrls, StdCtrls, ExtCtrls, Grids, Calendar, DBCtrls, Mask,
  DB, DBTables, DBGrids, Gauges, Registry, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP, IdExplicitTLSClientServerBase, IdFTP,
  IdZLibCompressorBase, ShellAPI, ShlObj, IdCompressorZLib, StrUtils;

type
  TfrmMain = class(TForm)
    pnlNav: TPanel;
    btnNewSpec: TButton;
    btnManSpec: TButton;
    btnNewConv: TButton;
    btnFtpUp: TButton;
    BtnExit: TButton;
    pgCtrl: TPageControl;
    tabIntro: TTabSheet;
    tabNewSpec: TTabSheet;
    tabManSpec: TTabSheet;
    tabNewConv: TTabSheet;
    btnDashboard: TButton;
    pnlIntro: TPanel;
    pnlNewSpec: TPanel;
    pnlManSpec: TPanel;
    pnlNewConv: TPanel;
    lblSpecName: TLabel;
    lblNewSpecHd: TLabel;
    dbedtSpecName: TDBEdit;
    dbedtPNumStart: TDBEdit;
    lblPNumStart: TLabel;
    lblPNumSize: TLabel;
    dbedtPNumSize: TDBEdit;
    dbchkPDesc: TDBCheckBox;
    lblPDescStart: TLabel;
    lblPDescSize: TLabel;
    dbedtPDescStart: TDBEdit;
    dbedtPDescSize: TDBEdit;
    dbchkPSuper: TDBCheckBox;
    dbedtPSupSize: TDBEdit;
    dbedtPSupStart: TDBEdit;
    lblPSuperStart: TLabel;
    lblPSupSize: TLabel;
    dbchkPRetPrice: TDBCheckBox;
    lblPRetStart: TLabel;
    lblPRetSize: TLabel;
    dbedtPRetPriceStart: TDBEdit;
    dbedtPRetPriceSize: TDBEdit;
    dbchkPMinOrder: TDBCheckBox;
    dbedtPMinOrdSize: TDBEdit;
    dbedtPMinOrdStart: TDBEdit;
    lblPMinOrdStart: TLabel;
    lblPMinOrdSize: TLabel;
    lblPGrpCodeStart: TLabel;
    lblPGrpCodeSize: TLabel;
    dbchkPGrpCode: TDBCheckBox;
    dbedtPGrpCStart: TDBEdit;
    dbedtPGrpCSize: TDBEdit;
    dbedtPRetDiv: TDBEdit;
    lblPRetDiv: TLabel;
    dbchkPCost: TDBCheckBox;
    dbedtPCostStart: TDBEdit;
    dbedtPCostSize: TDBEdit;
    lblPCostStart: TLabel;
    lblPCostSize: TLabel;
    lblPCostDiv: TLabel;
    dbedtPCostDiv: TDBEdit;
    dbedtPDisc: TDBCheckBox;
    lblPDiscStart: TLabel;
    lblPDiscSize: TLabel;
    dbedtPDiscStart: TDBEdit;
    dbedtPDiscSize: TDBEdit;
    dbedtPSur: TDBCheckBox;
    dbedtPSurStart: TDBEdit;
    dbedtPSurSize: TDBEdit;
    dbedtPSurDiv: TDBEdit;
    lblPSurStart: TLabel;
    lblPSurSize: TLabel;
    lblPSurDiv: TLabel;
    dbedtPUoi: TDBCheckBox;
    dbedtPUoiSize: TDBEdit;
    dbedtPUoiStart: TDBEdit;
    dbEdtPWeightSize: TDBEdit;
    lblPUoiStart: TLabel;
    lblPUoiSize: TLabel;
    dbchkPWeight: TDBCheckBox;
    dbedtPWeightStart: TDBEdit;
    lblPWeightStart: TLabel;
    lblPWeightSize: TLabel;
    lblPSuppStart: TLabel;
    lblPSuppSize: TLabel;
    dbedtPSupp: TDBCheckBox;
    dbedtPSuppStart: TDBEdit;
    dbedtPSuppSize: TDBEdit;
    btnSaveSpec: TButton;
    grdConvs: TDBGrid;
    grpSpecTools: TGroupBox;
    btnSpecEdit: TButton;
    btnCopySpec: TButton;
    btnDelSpec: TButton;
    grpConvStats: TGroupBox;
    grpFieldUse: TGroupBox;
    lblPSupUse: TLabel;
    lblPDescUse: TLabel;
    lblPGrpUse: TLabel;
    lblPMOrdUse: TLabel;
    lblPRetUse: TLabel;
    lblPCostUse: TLabel;
    lblPSurUse: TLabel;
    lblPDiscUse: TLabel;
    lblPUoiUse: TLabel;
    lblPWeightUse: TLabel;
    lblPSuppUse: TLabel;
    lblLastRan: TLabel;
    lblFirstRan: TLabel;
    lblTimesRan: TLabel;
    lblAvgRTime: TLabel;
    lblFirstRunD: TLabel;
    lblTimesRanNo: TLabel;
    lblAvgRunT: TLabel;
    lblLastEdit: TLabel;
    lblLastEditD: TLabel;
    lblCreated: TLabel;
    lblCreatedD: TLabel;
    pnlVer: TPanel;
    grpProgress: TGroupBox;
    prgTotal: TGauge;
    pgCtrlConv: TPageControl;
    tabStdConv: TTabSheet;
    tabAdvConv: TTabSheet;
    lblConvSel: TLabel;
    lblSrcFile: TLabel;
    tboxSrcFile: TEdit;
    btnStdBrowse: TButton;
    lblAliasSel: TLabel;
    cboxAliasSel: TComboBox;
    lblTableSel: TLabel;
    cboxTableSel: TComboBox;
    grpDestInfo: TGroupBox;
    btnStartConv: TButton;
    tboxCPPartsLoc: TEdit;
    tboxCPSupLoc: TEdit;
    btnAdvPartsBrowse: TButton;
    btnAdvSupBrowse: TButton;
    lblCPParts: TLabel;
    lblAdvSuperL: TLabel;
    lblIntroHd: TLabel;
    grpNotes: TGroupBox;
    dbmNotes: TDBMemo;
    btnSaveNotes: TButton;
    lblNoteCount: TLabel;
    btnSettings: TButton;
    tblSpecs: TTable;
    tblSystem: TTable;
    tblDest: TTable;
    dtsSystem: TDataSource;
    tblSystemVersion: TFloatField;
    tblSystemNotes: TMemoField;
    dtsSpecs: TDataSource;
    tblSpecsSpecName: TStringField;
    tblSpecsPNumStart: TFloatField;
    tblSpecsPNumSize: TFloatField;
    tblSpecsPDescEnabled: TBooleanField;
    tblSpecsPDescStart: TFloatField;
    tblSpecsPDescSize: TFloatField;
    tblSpecsPSupEnabled: TBooleanField;
    tblSpecsPSupStart: TFloatField;
    tblSpecsPSupSize: TFloatField;
    tblSpecsPGrpEnabled: TBooleanField;
    tblSpecsPGrpStart: TFloatField;
    tblSpecsPGrpSize: TFloatField;
    tblSpecsPMinOrdEnabled: TBooleanField;
    tblSpecsPMinOrdStart: TFloatField;
    tblSpecsPMinOrdSize: TFloatField;
    tblSpecsPRetEnabled: TBooleanField;
    tblSpecsPRetStart: TFloatField;
    tblSpecsPRetSize: TFloatField;
    tblSpecsPCostEnabled: TBooleanField;
    tblSpecsPCostStart: TFloatField;
    tblSpecsPCostSize: TFloatField;
    tblSpecsPSurcEnabled: TBooleanField;
    tblSpecsPSurcStart: TFloatField;
    tblSpecsPSurcSize: TFloatField;
    tblSpecsPDiscEnabled: TBooleanField;
    tblSpecsPDiscStart: TFloatField;
    tblSpecsPDiscSize: TFloatField;
    tblSpecsPUOIEnabled: TBooleanField;
    tblSpecsPUOIStart: TFloatField;
    tblSpecsPUOISize: TFloatField;
    tblSpecsPWeightEnabled: TBooleanField;
    tblSpecsPWeightStart: TFloatField;
    tblSpecsPWeightSize: TFloatField;
    tblSpecsPSuppEnabled: TBooleanField;
    tblSpecsPSuppStart: TFloatField;
    tblSpecsPSuppSize: TFloatField;
    tblSpecsLastRan: TDateField;
    tblSpecsLastEdit: TDateField;
    tblSpecsCreated: TDateField;
    tblSpecsTimesRan: TFloatField;
    tblSpecsAvgRunTime: TFloatField;
    btnNewSpecCanc: TButton;
    btnSpecExport: TButton;
    dbcConvList: TDBLookupComboBox;
    FetchVer: TIdHTTP;
    tabSettings: TTabSheet;
    pnlSettings: TPanel;
    btnRenameSpec: TButton;
    cboxAdvConv: TComboBox;
    tabGeneral: TTabSheet;
    tabFtp: TTabSheet;
    chkAutoUpdate: TDBCheckBox;
    lblConvStatusL: TLabel;
    lblConvStatus: TLabel;
    lblPartCountL: TLabel;
    lblPartCount: TLabel;
    tblSpecsPRetDiv: TFloatField;
    tblSpecsPCostDiv: TFloatField;
    tblSpecsPSurcDiv: TFloatField;
    tblDestPartNumber: TStringField;
    tblDestDescription: TStringField;
    tblDestSupersession: TStringField;
    tblDestGroupCode: TStringField;
    tblDestMinOrder: TFloatField;
    tblDestRetail: TCurrencyField;
    tblDestCost: TCurrencyField;
    tblDestDisc: TStringField;
    tblDestSurcharge: TCurrencyField;
    tblDestUoi: TFloatField;
    tblDestWeight: TFloatField;
    tblDestSupplier: TStringField;
    lblElapsedL: TLabel;
    lblElapsedTime: TLabel;
    lblRecPSecL: TLabel;
    lblRecPSec: TLabel;
    lblPartNumFill: TLabel;
    chkPartNum: TCheckBox;
    chkAutoEmpty: TDBCheckBox;
    tblSettings: TTable;
    tblSettingsOptAutoUpdate: TBooleanField;
    tblSettingsOptAutoEmpty: TBooleanField;
    dtsSettings: TDataSource;
    ConvTimer: TTimer;
    btnCancelStdConv: TButton;
    lblLastRanD: TLabel;
    lblConvInProg: TLabel;
    tblFtp: TTable;
    dtsFTP: TDataSource;
    tblFtpFTPHost: TStringField;
    tblFtpPort: TFloatField;
    tblFtpUsername: TStringField;
    tblFtpPassword: TStringField;
    tblFtpFTPDirectory: TStringField;
    dbedtFtpHost: TDBEdit;
    dbedtUsername: TDBEdit;
    dbedtPassword: TDBEdit;
    dbedtPort: TDBEdit;
    lblFtpDir: TLabel;
    lblFTPUser: TLabel;
    lblPassword: TLabel;
    lblFtpPort: TLabel;
    grpFtpSettings: TGroupBox;
    btnFTPTest: TButton;
    FTPClient: TIdFTP;
    mFTPOutput: TMemo;
    btnPassMask: TButton;
    btnSaveFTP: TButton;
    FTPUpload: TTabSheet;
    pnlFtpUpload: TPanel;
    tblSettingsOptAutoArchive: TBooleanField;
    dbedtConvOutDir: TDBEdit;
    btnOutputDir: TButton;
    chkAutoMove: TDBCheckBox;
    tblSettingsOptAutoMove: TBooleanField;
    tblSettingsOptAutoMoveDir: TStringField;
    pnlMore: TPanel;
    lblSpecMore: TLabel;
    chkAppPNum: TDBCheckBox;
    dbedtAppChar: TDBEdit;
    chkTrimPNum: TDBCheckBox;
    btnAdvanced: TButton;
    chkPadPNum: TDBCheckBox;
    dbedtPadChar: TDBEdit;
    lblPadLength: TLabel;
    dbedtPadSize: TDBEdit;
    lblPadChar: TLabel;
    dbedtTrimSize: TDBEdit;
    lblTrimChars: TLabel;
    chkAppSuper: TDBCheckBox;
    chkPadSuper: TDBCheckBox;
    chkTrimSuper: TDBCheckBox;
    pnlSpecAdvApply: TPanel;
    chkApplyPerm: TDBCheckBox;
    lblMoreWarn: TLabel;
    lblTrimHelp: TLabel;
    tblSpecsFirstRun: TDateField;
    tblSpecsAdvAppPNum: TBooleanField;
    tblSpecsAdvAppChar: TStringField;
    tblSpecsAdvAppSuper: TBooleanField;
    tblSpecsAdvPadPNum: TBooleanField;
    tblSpecsAdvPadChar: TStringField;
    tblSpecsAdvPadSize: TFloatField;
    tblSpecsAdvPadSuper: TBooleanField;
    tblSpecsAdvTrimPNum: TBooleanField;
    tblSpecsAdvTrimSuper: TBooleanField;
    tblSpecsAdvTemp: TBooleanField;
    lblAdvOpt: TLabel;
    tblSpecsAdvTrimSize: TFloatField;
    btnAdvSpec: TButton;
    tabOutput: TTabSheet;
    chkOrdDir: TDBCheckBox;
    chkMasterFile: TDBCheckBox;
    Label1: TLabel;
    Label2: TLabel;
    chkRename: TDBCheckBox;
    tblSettingsOptOrdDir: TBooleanField;
    tblSettingsOptMasterFile: TBooleanField;
    tblSettingsOptRenameFile: TBooleanField;
    lblDirMngrIntro: TLabel;
    grpDirStruct: TGroupBox;
    Label10: TLabel;
    Label9: TLabel;
    Label8: TLabel;
    Label7: TLabel;
    Label6: TLabel;
    Label5: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure btnDashboardClick(Sender: TObject);
    procedure btnNewSpecClick(Sender: TObject);
    procedure btnManSpecClick(Sender: TObject);
    procedure btnNewConvClick(Sender: TObject);
    procedure BtnExitClick(Sender: TObject);
    function GetProgamFiles : string;
    procedure cboxAliasSelChange(Sender: TObject);
    procedure dbmNotesExit(Sender: TObject);
    procedure btnDelSpecClick(Sender: TObject);
    procedure btnSaveSpecClick(Sender: TObject);
    procedure btnNewSpecCancClick(Sender: TObject);
    procedure btnSaveNotesClick(Sender: TObject);
    procedure grdConvsCellClick(Column: TColumn);
    procedure btnSpecEditClick(Sender: TObject);
    procedure btnSettingsClick(Sender: TObject);
    procedure pgCtrlChange(Sender: TObject);
    procedure btnRenameSpecClick(Sender: TObject);
    procedure btnCopySpecClick(Sender: TObject);
    procedure btnSpecExportClick(Sender: TObject);
    procedure btnStdBrowseClick(Sender: TObject);
    procedure btnStartConvClick(Sender: TObject);
    procedure pgCtrlConvChange(Sender: TObject);
    procedure btnCancelStdConvClick(Sender: TObject);
    procedure tabNewSpecExit(Sender: TObject);
    procedure tabNewSpecShow(Sender: TObject);
    procedure StandardConv;
    function FetchLines(srcFile: string): integer;
    function NumbersConv(Start, Size, Division: integer): Double;
    procedure ConvInProg(lvEnable: Boolean);
    procedure UpdateConvProg;
    procedure tabIntroShow(Sender: TObject);
    procedure UpdateConvInfo(Action: String);
    procedure dbmNotesChange(Sender: TObject);
    procedure btnFTPTestClick(Sender: TObject);
    procedure btnPassMaskMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btnPassMaskMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btnSaveFTPClick(Sender: TObject);
    procedure btnOutputDirClick(Sender: TObject);
    function BrowseDialog
    (const Title: string; const Flag: integer): string;
    procedure btnAdvancedClick(Sender: TObject);
    procedure lblTrimHelpClick(Sender: TObject);
    procedure btnAdvSpecClick(Sender: TObject);
    procedure Label1Click(Sender: TObject);
    procedure chkOrdDirClick(Sender: TObject);
    procedure chkAutoMoveClick(Sender: TObject);
    procedure chkAppPNumClick(Sender: TObject);
    procedure chkPadPNumClick(Sender: TObject);
    procedure chkTrimPNumClick(Sender: TObject);
  private
    procedure AutoMove;
    function CheckAdv(SpecName: string): boolean;
    { Private declarations }
  public
  end;

var
  frmMain      : TfrmMain;
  lvUseAlias   : string;
  lvTableList  : TStringList;
  lvWebVer     : Double;

  lvLineIn     : string;
  lvCurrent    : integer;
  lvCancel     : boolean;

  lvSelected   : string;
  lvSpecNew    : boolean;
  lvSpecEdit   : boolean;
  lvSpecRename : boolean;
  lvSpecCopy   : boolean;

implementation

uses SpecName, specexport, Updater;

{$R *.dfm}

{$REGION 'Navigation bar'}
procedure TfrmMain.btnDashboardClick(Sender: TObject);
begin
  pgCtrl.ActivePageIndex := 0;
end;

procedure TfrmMain.btnNewSpecClick(Sender: TObject);
var
  SpecName: TfrmSpecName;
begin
  lvSpecNew := True;
  pgCtrl.ActivePageIndex := 1;
  lblNewSpecHD.Caption := 'New Specification';
  SpecName := TfrmSpecName.Create(Application);
  try
    SpecName.ShowModal;
  finally
    SpecName.Free;
  end;
end;

procedure TfrmMain.btnOutputDirClick(Sender: TObject);
begin
  dbedtConvOutDir.Text := BrowseDialog('Output Folder', 1);
end;

procedure TfrmMain.btnRenameSpecClick(Sender: TObject);
var
  SpecRename: TfrmSpecName;
begin
  lvSpecRename := True;
  lvSelected := grdConvs.SelectedField.Value;
  SpecRename := TfrmSpecName.Create(Application);
  try
    SpecRename.ShowModal;
  finally
    SpecRename.Free;
  end;
end;

procedure TfrmMain.btnFTPTestClick(Sender: TObject);
begin
 try
  if FTPClient.Connected then
    FTPClient.Disconnect
  else
  begin
    FTPClient.Host     := tblFtpFTPHost.AsString;
    FTPClient.Username := tblFTPUsername.AsString;
    FTPClient.Password := tblFTPPassword.AsString;
    FTPClient.Port     := tblFTPPort.AsInteger;
    FTPClient.Connect;

    mFTPOutput.Text    := 'Successful Connection!';
  end;
 except
  On E : Exception do
    mFTPOutput.Text    := 'Connection Failed: ' + E.Message;
 end;
end;

procedure TfrmMain.btnManSpecClick(Sender: TObject);
begin
  pgCtrl.ActivePageIndex := 2;
end;

procedure TfrmMain.btnNewConvClick(Sender: TObject);
begin
  pgCtrl.ActivePageIndex := 3;
end;

procedure TfrmMain.btnSettingsClick(Sender: TObject);
begin
  pgCtrl.ActivePageIndex := 4;
end;

procedure TfrmMain.BtnExitClick(Sender: TObject);
begin

  if (MessageDlg('Are you sure you wish to exit?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
  begin
    tblSystem.Edit;
    tblSystem.Post;

    tblSettings.Edit;
    tblSettings.Post;

    tblFTP.Edit;
    tblFTP.Post;

    tblFTP.Close;
    tblSystem.Close;
    tblSettings.Close;
    tblSpecs.Close;

    Self.Close;
  end;
end;

procedure TfrmMain.tabIntroShow(Sender: TObject);
begin
  ConvInProg(False);
end;

procedure TfrmMain.tabNewSpecExit(Sender: TObject);
begin
  ConvInProg(False);
end;

procedure TfrmMain.tabNewSpecShow(Sender: TObject);
begin
  ConvInProg(True);
end;

{$ENDREGION}

{$REGION 'Overview'}
procedure TfrmMain.dbmNotesChange(Sender: TObject);
begin
  lblNoteCount.Caption := IntToStr(Length(dbmNotes.Text));
end;

procedure TfrmMain.dbmNotesExit(Sender: TObject);
begin
  tblSystem.Post;
end;

procedure TfrmMain.btnSaveFTPClick(Sender: TObject);
begin
  tblFTP.Edit;
  tblFTP.Post;
end;

procedure TfrmMain.btnSaveNotesClick(Sender: TObject);
begin
  tblSystem.Edit;
  tblSystem.Post;
end;
{$ENDREGION}

{$REGION 'Run Conversion'}
procedure TfrmMain.cboxAliasSelChange(Sender: TObject);
begin
  // Populate cbox table selection with a list of all tables within the selected alias
  lvTableList := TStringList.Create;
  try
    session.GetTableNames(cboxAliasSel.Text,'',True,False,lvTableList);
    cboxTableSel.Items := lvTableList;
  finally
    lvTableList.Free;
    cboxTableSel.ItemIndex := 0;
  end;
end;

// Advanced settings - Start
procedure TfrmMain.chkAppPNumClick(Sender: TObject);
begin
  dbedtAppChar.Enabled := chkAppPNum.Checked;
  chkAppSuper.Enabled  := chkAppPNum.Checked;
  chkApplyPerm.Checked := CheckAdv(dbcConvList.Text);
end;

procedure TfrmMain.chkPadPNumClick(Sender: TObject);
begin
  dbedtPadChar.Enabled := chkPadPNum.Checked;
  lblPadLength.Enabled := chkPadPNum.Checked;
  dbedtPadSize.Enabled := chkPadPNum.Checked;
  lblPadChar.Enabled   := chkPadPNum.Checked;
  chkPadSuper.Enabled  := chkPadPNum.Checked;
  chkApplyPerm.Checked := CheckAdv(dbcConvList.Text);
end;

procedure TfrmMain.chkTrimPNumClick(Sender: TObject);
begin
  dbedtTrimSize.Enabled := chkTrimPNum.Checked;
  lblTrimChars.Enabled  := chkTrimPNum.Checked;
  lblTrimHelp.Enabled   := chkTrimPNum.Checked;
  chkTrimSuper.Enabled  := chkTrimPNum.Checked;
  chkApplyPerm.Checked := CheckAdv(dbcConvList.Text);
end;
// Advanced settings - End

{$ENDREGION}

{$REGION 'New Specification'}
procedure TfrmMain.btnSaveSpecClick(Sender: TObject);
begin
  if lvSpecEdit then
    if (MessageDlg('Are you sure you wish to update this specification?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
    begin
      UpdateConvInfo('Edit');
      tblSpecs.Edit;
      tblSpecs.Post;
    end;

  pgCtrl.ActivePageIndex := 2;
end;

procedure TfrmMain.btnNewSpecCancClick(Sender: TObject);
begin
  if (MessageDlg('Are you sure you wish to cancel and erase your current progress?', mtWarning, [mbYes, mbNo], 0) = mrYes) then
  begin
    tblSpecs.Cancel;
    pgctrl.ActivePageIndex := 2;
  end;
end;
{$ENDREGION}

{$REGION 'Manage Specifications'}
procedure TfrmMain.btnSpecEditClick(Sender: TObject);
begin
  if (MessageDlg('Are you sure you wish to edit this specification?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
  begin
    lvSpecEdit := True;
    if tblSpecs.FindKey([grdConvs.SelectedField.AsString]) then
    begin
      tblSpecs.Edit;
      pgCtrl.ActivePageIndex := 1;
      lblNewSpecHD.Caption := 'Edit Specification';
    end;
  end;
end;

procedure TfrmMain.btnCopySpecClick(Sender: TObject);
var
  SpecCopy: TfrmSpecName;
begin
  lvSpecCopy := True;
  lvSelected := grdConvs.SelectedField.Value;
  SpecCopy := TfrmSpecName.Create(Application);
  try
    SpecCopy.ShowModal;
  finally
    SpecCopy.Free;
  end;
end;

procedure TfrmMain.btnSpecExportClick(Sender: TObject);
var
  SpecExport: TfrmSpecExport;
begin
  SpecExport := TfrmSpecExport.Create(Application);
  try
    SpecExport.ShowModal;
  finally
    SpecExport.Free;
  end;
end;

procedure TfrmMain.btnStartConvClick(Sender: TObject);
var
  lvActivePage: integer;
begin
  lvActivePage := pgCtrlConv.ActivePageIndex;
  lvCancel     := False;

  if prgTotal.Progress > 0 then
    prgTotal.Progress := 0;

  if (MessageDlg('Are you sure you wish to run the ' + dbcConvList.Text + ' conversion?',
  mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
  begin
    pgCtrlConv.ActivePageIndex := 2;
    ConvInProg(True);
    StandardConv;
    ConvInProg(False);
    pgCtrlConv.ActivePageIndex := lvActivePage;
  end;
end;

procedure TfrmMain.btnStdBrowseClick(Sender: TObject);
var
  openDialog : TOpenDialog;
begin
  openDialog := TOpenDialog.Create(self);
  openDialog.InitialDir := 'C:\';
  openDialog.Options := [ofFileMustExist];
  openDialog.Filter := 'Text Files|*.txt|All Files|*.*';
  openDialog.FilterIndex := 1;

  if openDialog.Execute then
    tboxSrcFile.Text := openDialog.FileName;

  openDialog.Free;
end;

procedure TfrmMain.btnPassMaskMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  dbedtPassword.PasswordChar := #0;
end;

procedure TfrmMain.btnPassMaskMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  dbedtPassword.PasswordChar := '*';
end;

procedure TfrmMain.btnAdvancedClick(Sender: TObject);
begin
  if dbcConvList.Text <> '' then
    begin
    if self.Width = 590 then
    begin
      self.Width := 780;
      btnAdvanced.Caption := 'Less <<';
    end
    else
    begin
      self.Width := 590;
      btnAdvanced.Caption := 'More >>';
    end;
  end;
end;

procedure TfrmMain.btnAdvSpecClick(Sender: TObject);
begin
  if self.Width = 590 then
  begin
    self.Width := 780;
    btnAdvSpec.Caption := 'Less <<';
    pnlSpecAdvApply.Visible := False;
  end
  else
  begin
    self.Width := 590;
    btnAdvSpec.Caption := 'More >>';
    pnlSpecAdvApply.Visible := True;
  end;
end;

procedure TfrmMain.btnCancelStdConvClick(Sender: TObject);
begin
  if (MessageDlg('Are you sure you wish to stop the current conversion?', mtWarning, [mbYes, mbNo], 0) in [mrYes, mrNone]) then
    lvCancel := True;
end;

procedure TfrmMain.btnDelSpecClick(Sender: TObject);
begin
  if (MessageDlg('Are you sure you wish to delete the selected items?', mtWarning, [mbYes, mbNo], 0) = mrYes) then
    tblSpecs.Delete;

  grdConvs.Repaint;
end;

procedure TfrmMain.grdConvsCellClick(Column: TColumn);
begin
  if tblSpecs.FindKey([grdConvs.SelectedField.AsString]) then
  begin
    lblPSupUse.Enabled    := tblSpecsPSupEnabled.AsBoolean;
    lblPDescUse.Enabled   := tblSpecsPDescEnabled.AsBoolean;
    lblPGrpUse.Enabled    := tblSpecsPGrpEnabled.AsBoolean;
    lblPMOrdUse.Enabled   := tblSpecsPMinOrdEnabled.AsBoolean;
    lblPRetUse.Enabled    := tblSpecsPRetEnabled.AsBoolean;
    lblPCostUse.Enabled   := tblSpecsPCostEnabled.AsBoolean;
    lblPSurUse.Enabled    := tblSpecsPSurcEnabled.AsBoolean;
    lblPDiscUse.Enabled   := tblSpecsPDiscEnabled.AsBoolean;
    lblPUoiUse.Enabled    := tblSpecsPUoiEnabled.AsBoolean;
    lblPWeightUse.Enabled := tblSpecsPWeightEnabled.AsBoolean;
    lblPSuppUse.Enabled   := tblSpecsPSuppEnabled.AsBoolean;

    lblFirstRunD.Caption  := tblSpecsFirstRun.AsString;
    lblLastRanD.Caption   := tblSpecsLastRan.AsString;
    lblLastEditD.Caption  := tblSpecsLastEdit.AsString;
    lblCreatedD.Caption   := tblSpecsCreated.AsString;
    lblTimesRanNo.Caption := tblSpecsTimesRan.AsString;
    lblAvgRunT.Caption    := tblSpecsAvgRunTime.AsString;
  end;

  if tblSpecs.State in [dsEdit, dsInsert] then
    tblSpecs.Post;
end;

procedure TfrmMain.Label1Click(Sender: TObject);
begin
  ShowMessage('This will use the file ''Master.db'' within the GIPM alias as the price file template for every conversion, this ' +
              'negates the use of providing GIPM with an output Alias/Table.' + #13#10 + #13#10 +
              'Checking this option will also force the file to be ' +
              'copied to the the output directory and will be renamed from ''Master.db'' to the name of the conversion ran, i.e. ' +
              '''pTest.db'', this is not enabled by default but is recomended.');
end;

procedure TfrmMain.lblTrimHelpClick(Sender: TObject);
begin
  ShowMessage('If you are just wanting to trim all of the zeros from the part number, put a zero in the box.');
end;

{$ENDREGION}

{$REGION 'Startup, Closing, Misc'}
procedure TfrmMain.FormCreate(Sender: TObject);
var
  I : Integer;
  lvAliasList  : TStringList;
  SystemUpdate : TfrmUpdate;
begin
  // Set form dimensions
  self.Height := 330;
  self.Width  := 590;

  // Remove old exe after update
  if FileExists('update.exe') then
    DeleteFile('update.exe');

  // Hide tabs
  for I := 0 to (pgCtrl.ControlCount - 1) do
    if pgCtrl.Controls[I] is TTabSheet then
      TTabSheet(pgCtrl.Controls[I]).TabVisible := False;

  pgCtrl.ActivePageIndex    := 0;

  // Populate Alias select cbox
  lvAliasList := TStringList.Create;
  try
    session.GetAliasNames(lvAliasList);
    cboxAliasSel.Items := lvAliasList;
  finally
    lvAliasList.Free;
  end;

  // Open tables
  tblSystem.Open;
  tblSystem.First;
  tblSystem.Edit;

  tblSpecs.Open;
  tblSpecs.First;
  tblSpecs.Edit;

  tblSettings.Open;
  tblSettings.First;
  tblSettings.Edit;

  tblFTP.Open;
  tblFTP.First;
  tblFTP.Edit;

  // Check online version
  if tblSettingsOptAutoUpdate.AsBoolean then
  begin
    Try
      Try
        lvWebVer := StrToFloat(FetchVer.Get('http://www.moonpunchstudios.co.uk/software/gipm/gipmversion.html'));

      if lvWebVer > tblSystemVersion.AsFloat then
      begin
        SystemUpdate := TfrmUpdate.Create(Application);
        try
          SystemUpdate.ShowModal;
        finally
          SystemUpdate.Free;
        end;
      end;
      Finally
        pnlVer.Caption := 'v' + FloatToStr(tblSystemVersion.AsFloat);
      End;
    Except
      On E : Exception do
        ShowMessage('Checking for updates failed due to the following error: ' + #13#10 + E.Message +  #13#10 + #13#10 +
                    'You must be connected to the internet to receive updates.' + #13#10 +
                    'You can prevent this message from showing by disabling the version check which can be found in the ''System Settings''.');
    end;
  end;
end;

procedure TfrmMain.pgCtrlChange(Sender: TObject);
begin
  if pgCtrl.ActivePageIndex = 1 then
    ConvInProg(True)
  else
    ConvInProg(False);

  if tblSystem.State   in [dsEdit, dsInsert] then
    tblSystem.Post;

  if tblSpecs.State    in [dsEdit, dsInsert] then
    tblSpecs.Post;

  if tblSettings.State in [dsEdit, dsInsert] then
    tblSettings.Post;

end;
procedure TfrmMain.pgCtrlConvChange(Sender: TObject);
begin

end;

{$ENDREGION}

{$REGION 'Settings'}
procedure TfrmMain.chkAutoMoveClick(Sender: TObject);
begin
  dbedtConvOutDir.Enabled := chkAutoMove.Checked;
  btnOutputDir.Enabled    := chkAutoMove.Checked;

  if not chkAutoMove.Checked then
    if chkOrdDir.Checked then
      chkOrdDir.Checked   := False;
end;

procedure TfrmMain.chkOrdDirClick(Sender: TObject);
begin
  grpDirStruct.Visible    := chkOrdDir.Checked;
  lblDirMngrIntro.Visible := chkOrdDir.Checked;

  if not chkAutoMove.Checked then
    chkAutoMove.Checked   := chkOrdDir.Checked;
end;
{$ENDREGION}

{$REGION 'Custom Functions/Procedures'}
procedure TfrmMain.StandardConv;
var
  lvSrcFile   : TextFile;
  lvPartNum   : string;

  lvDestAlias : string;
  lvDestTable : string;

  lvSrcTot    : integer;
begin
  // Update specification info
  UpdateConvInfo('Running');

  // Configure initial progress
  lblConvStatus.Caption := 'Processing source...';
  lvSrcTot := FetchLines(tboxSrcFile.Text);
  prgTotal.MinValue     := 0;
  prgTotal.MaxValue     := lvSrcTot;
  lblPartCount.Caption  := IntToStr(lvSrcTot);

  // Configure destination
  lvDestAlias := cboxAliasSel.Text;
  lvDestTable := cboxTableSel.Text;
  tblDest.DatabaseName  := lvDestAlias;
  tblDest.TableName     := lvDestTable;

  // Check destination table
  tblDest.Open;
  if tblDest.RecordCount > 0 then
    if not tblSettingsOptAutoEmpty.AsBoolean then
    begin
      if (MessageDlg('The destination table contains records, would you like to empty the table before proceeding?',
        mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
      begin
        tblDest.Close;
        tblDest.Active := False;
        tblDest.EmptyTable;
      end;
    end
    else
    begin
      tblDest.Close;
      tblDest.Active := False;
      tblDest.EmptyTable;
    end;

  lblConvStatus.Caption := 'Converting...';

  tblDest.Open;
  tblDest.First;

  AssignFile(lvSrcFile, tboxSrcFile.Text);
  Reset(lvSrcFile);

  while not EOF(lvSrcFile) and not lvCancel do
  begin
    ReadLn(lvSrcFile, lvLineIn);

    lvPartNum := Copy(lvLineIn, tblSpecsPNumStart.AsInteger,  tblSpecsPNumSize.AsInteger);

    if tblDest.FindKey([lvPartNum]) then
      tblDest.Edit
    else
      tblDest.Append;

    tblDestPartNumber.AsString     := lvPartNum;

    if tblSpecsPDescEnabled.AsBoolean then
      tblDestDescription.AsString  := Copy(lvLineIn, tblSpecsPDescStart.AsInteger, tblSpecsPDescSize.AsInteger);

    if tblSpecsPSupEnabled.AsBoolean then
      tblDestSupersession.AsString := Copy(lvLineIn, tblSpecsPSupStart.AsInteger,  tblSpecsPSupSize.AsInteger);

    if tblSpecsPGrpEnabled.AsBoolean then
      tblDestGroupCode.AsString    := Copy(lvLineIn, tblSpecsPGrpStart.AsInteger,  tblSpecsPGrpSize.AsInteger);

    if tblSpecsPDiscEnabled.AsBoolean then
      tblDestDisc.AsString         := Copy(lvLineIn, tblSpecsPDiscStart.AsInteger, tblSpecsPDiscSize.AsInteger);

    if tblSpecsPSuppEnabled.AsBoolean then
      tblDestSupplier.AsString     := Copy(lvLineIn, tblSpecsPSuppStart.AsInteger, tblSpecsPSuppSize.AsInteger);

    if tblSpecsPMinOrdEnabled.AsBoolean then
      tblDestMinOrder.AsFloat      := NumbersConv(tblSpecsPMinOrdStart.AsInteger,  tblSpecsPMinOrdSize.AsInteger, 0);

    if tblSpecsPUOIEnabled.AsBoolean then
      tblDestUoi.AsFloat           := NumbersConv(tblSpecsPUOIStart.AsInteger,     tblSpecsPUOISize.AsInteger,    0);

    if tblSpecsPWeightEnabled.AsBoolean then
      tblDestWeight.AsFloat        := NumbersConv(tblSpecsPWeightStart.AsInteger,  tblSpecsPWeightSize.AsInteger, 0);

    if tblSpecsPRetEnabled.AsBoolean then
      tblDestRetail.AsFloat        := NumbersConv(tblSpecsPRetStart.AsInteger,     tblSpecsPRetSize.AsInteger,    tblSpecsPRetDiv.AsInteger);

    if tblSpecsPCostEnabled.AsBoolean then
      tblDestCost.AsFloat          := NumbersConv(tblSpecsPCostStart.AsInteger,    tblSpecsPCostSize.AsInteger,   tblSpecsPCostDiv.AsInteger);

    if tblSpecsPSurcEnabled.AsBoolean then
      tblDestSurcharge.AsFloat     := NumbersConv(tblSpecsPSurcStart.AsInteger,    tblSpecsPSurcSize.AsInteger,   tblSpecsPSurcDiv.AsInteger);

    UpdateConvProg;
  end;

  if lvCancel then
  begin
    ShowMessage('Conversion stopped: Interupted by user.');
    lblConvStatus.Caption := 'Cancelled...';
    ConvInProg(False);
    prgTotal.Progress := 0;
    tblDest.Cancel;
  end
  else
  begin
    if tblDest.State in [dsEdit, dsInsert] then
      tblDest.Post;
  end;
  tblDest.Close;

  AutoMove;
  lblConvStatus.Caption := 'Complete';
end;

function TfrmMain.BrowseDialog
 (const Title: string; const Flag: integer): string;
var
  lpItemID : PItemIDList;
  BrowseInfo : TBrowseInfo;
  DisplayName : array[0..MAX_PATH] of char;
  TempPath : array[0..MAX_PATH] of char;
begin
  Result:='';
  FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
  with BrowseInfo do begin
    hwndOwner := Application.Handle;
    pszDisplayName := @DisplayName;
    lpszTitle := PChar(Title);
    ulFlags := Flag;
  end;
  lpItemID := SHBrowseForFolder(BrowseInfo);
  if lpItemId <> nil then begin
    SHGetPathFromIDList(lpItemID, TempPath);
    Result := TempPath;
    GlobalFreePtr(lpItemID);
  end;
end;

function TfrmMain.CheckAdv(SpecName: string): boolean;
begin
  if tblSpecsAdvAppPNum.AsBoolean or tblSpecsAdvPadPNum.AsBoolean or tblSpecsAdvTrimPNum.AsBoolean then
    Result := True
  else
    Result := False;
end;

function TfrmMain.NumbersConv(Start, Size, Division : integer): Double;
var
  lvTmpStr : string;
  lvTmpDbl : Double;
begin
  // No division should be define as 0
  lvTmpStr := Copy(lvLineIn, Start, Size);
  TryStrToFloat(lvTmpStr, lvTmpDbl);

  if Division > 0 then
  begin
    lvTmpDbl := lvTmpDbl / Division;
  end;

  Result := lvTmpDbl;
end;

procedure TFrmMain.UpdateConvProg;
begin
  Inc(lvCurrent, 1);
  prgTotal.AddProgress(1);
  Application.ProcessMessages;
end;

function TfrmMain.FetchLines(srcFile: string): integer;
var
  lvCount  : integer;
  lvSrcFile: TextFile;
  lvTmpStr : string;
begin
  AssignFile(lvSrcFile, srcFile);
  Reset(lvSrcFile);
  lvCount := 0;

  while not EOF(lvSrcFile) do
  begin
    Application.ProcessMessages;
    ReadLn(lvSrcFile, lvTmpStr);
    Inc(lvCount, 1);
  end;

  Result := lvCount;
end;

procedure TfrmMain.ConvInProg(lvEnable: Boolean);
var
  I: Integer;
  Control: TControl;
begin
  // Invert previous selection to cut down on code
  // this allows me to use the variable passed in as the
  // enabled/disabled state of the controls
  if lvEnable then lvEnable := False else lvEnable := True;

  for I := 0 to -1 + pnlNav.ControlCount do
  begin
    Control         := pnlNav.Controls[I];
    Control.Enabled := lvEnable;
  end;

  if pgCtrl.ActivePageIndex = 3 then
  begin
    pgCtrlConv.Visible        := lvEnable;
    dbcConvList.Enabled       := lvEnable;
    tboxSrcFile.Enabled       := lvEnable;
    btnStdBrowse.Enabled      := lvEnable;
    grpDestInfo.Enabled       := lvEnable;
    grpDestInfo.Visible       := lvEnable;
    btnStartConv.Visible      := lvEnable;

    if not lvEnable then
      btnCancelStdConv.Enabled := True
    else
      btnCancelStdConv.Enabled := False;
  end;

end;

procedure TfrmMain.AutoMove;
var
  lvSource: TStringList;
  lvTableName: string;
begin
  if tblSettingsOptAutoMove.AsBoolean then
  begin
    lvSource := TStringList.Create;
    lblConvStatus.Caption := 'Moving destination table...';

    // Fetch the location of the alias
    tblDest.DBSession.GetAliasParams(tblDest.DatabaseName, lvSource);
    lvSource[0] := StringReplace(lvSource[0], 'PATH=', '', [rfReplaceAll, rfIgnoreCase]);

    // Copy both .db file and .px
    lvTableName := StringReplace(tblDest.TableName, '.db', '', [rfReplaceAll, rfIgnoreCase]);
    CopyFile(PChar(lvSource[0] + '/' + lvTableName + '.db'), PChar(tblSettingsOptAutoMoveDir.AsString + '/' + lvTableName + '.db'), true);
    CopyFile(PChar(lvSource[0] + '/' + lvTableName + '.px'), PChar(tblSettingsOptAutoMoveDir.AsString + '/' + lvTableName + '.px'), true);
  end;
end;

procedure TfrmMain.UpdateConvInfo(Action: String);
begin
  if not tblSpecs.Active then
    tblSpecs.Open;

  tblSpecs.Edit;

// Spec Edit - Start
  if Action = 'Edit' then
  begin
    tblSpecsLastEdit.AsDateTime := Now;
  end;
// Spec Edit - End

// Spec Running - Start
  if Action = 'Running' then
  begin
    if tblSpecsLastRan.IsNull then
      begin
        tblSpecsFirstRun.AsDateTime := Now;
        tblSpecsLastRan.AsDateTime  := Now;
      end
      else
      begin
        tblSpecsLastRan.AsDateTime  := Now;
      end;

      tblSpecsTimesRan.AsInteger    := tblSpecsTimesRan.AsInteger + 1;
  end;
// Spec Running - End
  tblSpecs.Post;
end;

function TfrmMain.GetProgamFiles : string;
var
  reg : TRegistry;
begin
  reg:= TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion', False);
    Result := reg.ReadString('ProgramFilesDir');
  finally
    reg.Free;
  end;
end;
{$ENDREGION}
end.
